/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行，false 表非立即执行
 *
 * 默认选择立即执行版本
 * 立即执行版的意思是触发事件后函数会立即执行，然后 n 秒内不触发事件才能继续执行函数的效果。
 */

export function debounce(fn: any, wait: any, immediate = false) {
  let timer: any,
    startTimeStamp = 0
  let context: any, args: any
  const run = (timerInterval: any) => {
    timer = setTimeout(() => {
      const now = new Date().getTime()
      const interval = now - startTimeStamp
      if (interval < timerInterval) {
        // the timer start time has been reset，so the interval is less than timerInterval
        startTimeStamp = now
        run(wait - interval) // reset timer for left time
      } else {
        if (!immediate) {
          fn.apply(context, args)
        }
        clearTimeout(timer)
        timer = null
      }
    }, timerInterval)
  }

  return function (_data?: any) {
    // @ts-ignore
    context = this
    args = arguments
    const now = new Date().getTime()
    startTimeStamp = now // set timer start time
    if (!timer) {
      if (immediate) {
        fn.apply(context, args)
      }
      run(wait) // last timer alreay executed, set a new timer
    }
  }
}

/**
 * @desc function 需要节流的函数
 * wait [number] 毫秒 执行间隔时间
 * */
export function throttle(fn: any, wait: any, immediate?: any) {
  let timer: any,
    timeStamp = 0
  let context: any, args: any
  const run = () => {
    timer = setTimeout(() => {
      if (!immediate) {
        fn.apply(context, args)
      }
      clearTimeout(timer)
      timer = null
    }, wait)
  }
  return function (_data?: any) {
    // @ts-ignore
    context = this
    args = arguments
    if (!timer) {
      if (immediate) {
        fn.apply(context, args)
      }
      run()
    } else {
      console.log('throttle, ignore')
    }
  }
}
